import 'package:dio/dio.dart';
import 'package:share_fit/app/controllers/base/base_controller.dart';
import 'package:share_fit/app/controllers/main/login/http_const.dart';
import 'package:share_fit/app/controllers/space/person/person_const.dart';
import 'package:share_fit/app/controllers/space/person/person_state.dart';
import 'package:share_fit/app/network/net_const.dart';
import 'package:share_fit/app/network/net_tool.dart';
import 'package:share_fit/app/tools/app_util.dart';
import 'package:share_fit/app/tools/unit_util.dart';

class PersonLogic extends BaseController {

  final PersonState state = PersonState();

  void loadPersonalData() {
    state.avatar = read('space_avatar_path', defaultValue: '', global: true);
    state.nickName = read('space_person_name', defaultValue: '', global: true);

    state.genderIndex = read(PersonConst.spacePersonGender, defaultValue: -1, global: true);
    state.ageIndex = read(PersonConst.spacePersonAge, defaultValue: -1, global: true);
    state.personalHeight = read('space_person_height', defaultValue: -1, global: true);
    if (UnitUtil.isHeightUnitUS() && state.personalHeight > 0) {
      state.personalHeight = UnitUtil.cmToInches(state.personalHeight.toDouble());
    }
    state.personalWeight = read(PersonConst.spacePersonWeight, defaultValue: -1, global: true);
    if (UnitUtil.isWeightUnitUS() && state.personalWeight > 0) {
      state.personalWeight = UnitUtil.kgToLb(state.personalWeight.toDouble());
    }

    String date = read('register_info_date', defaultValue: '', global: true);
    if (date.isNotEmpty) {
      List<String> temp = date.split('-');
      DateTime dt = DateTime.utc(
          int.parse(temp[0]), int.parse(temp[1]), int.parse(temp[2]));
      state.ageIndex = getAge(dt) > 0 ? getAge(dt) - 1 : -1;
    }
  }

  void setAvatar(String url) {
    state.avatar = url;
    update(["person_avatar"]);
  }

  void setNickName(name) {
    state.nickName = name;
    update(["person_name"]);
  }

  void setGender(int value) {
    save(PersonConst.spacePersonGender, value, global: true);
    state.genderIndex = value;
    update(["person_gender"]);
  }

  void setAge(int value) {
    state.ageIndex = value;
    update(["person_age"]);
  }

  void setHeight(String value) {
    state.personalHeight = int.parse(value);
    if (UnitUtil.isHeightUnitUS()) {
      state.personalHeight = UnitUtil.inchesToCm(double.parse(value));
    }
    save(PersonConst.spacePersonHeight,  state.personalHeight, global: true);
    update(["person_height"]);
  }

  int getPersonalHeight() {
    if (UnitUtil.isHeightUnitUS()) {
      return UnitUtil.cmToInches(state.personalHeight.toDouble());
    }
    return state.personalHeight;
  }

  void setWeight(String value) {
    state.personalWeight = int.parse(value);
    if (UnitUtil.isWeightUnitUS()) {
      state.personalWeight = UnitUtil.lbToKg(double.parse(value));
    }
    save(PersonConst.spacePersonWeight, state.personalWeight, global: true);
    update(["person_weight"]);
  }

  int getPersonalWeight() {
    if (UnitUtil.isWeightUnitUS()) {
      return UnitUtil.kgToLb(state.personalWeight.toDouble());
    }

    return state.personalWeight;
  }

  void setBottomChecked(value) {
    state.isBottomSelected = value;
    update(['del_bottom_selected']);
  }

  int getAge(DateTime brt){
    int age = 0;
    DateTime dateTime = DateTime.now();
    if (brt.isAfter(dateTime)) { //出生日期晚于当前时间，无法计算
      return 0;
    }
    int yearNow = dateTime.year;  //当前年份
    int monthNow = dateTime.month;  //当前月份
    int dayOfMonthNow = dateTime.day; //当前日期

    int yearBirth = brt.year;
    int monthBirth = brt.month;
    int dayOfMonthBirth = brt.day;
    age = yearNow - yearBirth;   //计算整岁数
    if (monthNow <= monthBirth) {
      if (monthNow == monthBirth) {
        if (dayOfMonthNow < dayOfMonthBirth) age--;//当前日期在生日之前，年龄减一
      } else {
        age--;//当前月份在生日之前，年龄减一
      }
    }
    return age;
  }

  Future<dynamic> deleteAccount(orgPwd) async {
    var rsp = await checkPwd(orgPwd);
    var code = rsp[NetConst.keyCode];
    var message = rsp[NetConst.keyMessage];
    if (rsp[NetConst.keyCode] == NetConst.checkPwdSuccess) {
      final dio = Dio();
      // dio.options.contentType='application/x-www-form-urlencoded,application/json';
      dio.interceptors.add(LogInterceptor(requestBody: true, responseBody: true));
      dio.options.headers.addAll({'token':read(NetConst.keyUserToken, global: true)});
      try{
        String uid = read('login_id', defaultValue: '', global: true);
        Response response = await dio.delete('${HttpConst.regist_del}/$uid');
        code = response.data[NetConst.keyCode];
        message = response.data[NetConst.keyMessage];
      } catch (e) {
        if(e is DioException && e.response!=null) {
          code = e.response!.data[NetConst.keyCode];
          message = e.response!.data[NetConst.keyMessage];
        }
      }
    }

    return {NetConst.keyCode: code, NetConst.keyMessage: message};
  }

  Future<dynamic> checkPwd(String originalPwd) async {
    final dio = Dio();
    // dio.options.contentType='application/x-www-form-urlencoded,application/json';
    dio.interceptors.add(LogInterceptor(requestBody: true, responseBody: true));
    dio.options.headers.addAll(NetTool.getHeadersWithToken());
    dio.options.headers.addAll(NetTool.getHeadersWithLanguage());
    var code = NetConst.errorCodeDefault;
    var message = "";
    try{
      String userName = read('space_person_name', defaultValue: '', global: true);
      String params = '{"userName": "$userName", "originalPwd": "$originalPwd"}';

      Response response = await dio.post(HttpConst.check_pwd, data: params,);
      if(response.statusCode == NetConst.statusSuccess) {
        var retCode = response.data[NetConst.keyCode];
        code = retCode is String ? int.parse(retCode) : code;
        message = response.data[NetConst.keyMessage];
      }
    } catch (e) {
      if(e is DioException && e.response!=null) {
        var retCode = e.response!.data[NetConst.keyCode];
        code = retCode is String ? int.parse(retCode) : code;
        message = e.response!.data[NetConst.keyMessage];
      }
    }

    return {NetConst.keyCode: code, NetConst.keyMessage: message};
  }

  @override
  String getRemotePath() {
    return "";
  }

  @override
  void initState() {
    // TODO: implement initState
  }

  @override
  void onRemoteEvent(event, method) {
    // TODO: implement onRemoteEvent
  }

  void onDeleteAccount() {
    AppUtil.deleteAccountInfo(address: getAddress());
  }
}